
package reflect;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author Administrator
 */
public class Reflect{

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        Class clz = String.class;
        
        System.out.println("类名称" + clz.getName());
        System.out.println("是否为接口" + clz.isInterface());
        System.out.println("是否为基本类型" + clz.isPrimitive());
        System.out.println("是否为数组对象" + clz.isArray());
        System.out.println("父类名称" + clz.getSuperclass().getName());

        //Some s;
        //s = new Some();
        
        try {
            Class clazz = Class.forName("reflect.Reflect");
            System.out.println("类名称" + clazz.getName());
            System.out.println("是否为接口" + clazz.isInterface());
            System.out.println("是否为基本类型" + clazz.isPrimitive());
            System.out.println("是否为数组" + clazz.isArray());
            System.out.println("父类" + clazz.getSuperclass().getName());
        } catch (ClassNotFoundException e) {
            System.out.println("找不到类???" + e);
            //e.printStackTrace();
        }
        try {
            Class cl = Class.forName("reflect.Some", false, Some.class.getClassLoader());//加载.class文档时不会立即执行static区块
            System.out.println("已载入Some.class");
            Some ss;
            System.out.println("声明实例");
            ss = new Some();
            System.out.println("生成实例");
        } catch (Exception e) {
            //e.printStackTrace();
            System.out.println("找不到类???");
        }
        
        //Reflect.view("reflect.Hello");
        
        String playImpl = System.getProperty("reflect.PlayImpl");
        System.out.println(playImpl);
        Player player = (Player) Class.forName("reflect.PlayImpl").newInstance();
        player.play("影片名字");
        
        Class clas = Class.forName("reflect.Some");
        Constructor c = clas.getConstructor();
        Some s = (Some) c.newInstance();
        
        //动态生成长度为10的java.util.ArrayList数组
        Class classArray = java.util.ArrayList.class;
        Object obj = Array.newInstance(classArray, 10);
        Object[] objects = (Object[]) Array.newInstance(classArray, 10);
        objects[0] = new ArrayList();
        
        Class claStu = Class.forName("reflect.Student");
        Constructor constructor = claStu.getConstructor(String.class, Integer.class);
        Object o = constructor.newInstance("张三", 59);
        //指定方法名称与参数类型调用getMethod取得公开方法实例
        Method setter = claStu.getMethod("setName", String.class);
        //指定参数值调用对象o的方法
        setter.invoke(o, "李四");
        Method getter = claStu.getMethod("getName");
        System.out.println(getter.invoke(o));
        
        
        
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("name", "王二");
        data.put("score", 90);
        Student student = (Student) BeanUtil.getBean(data, "reflect.Student");
        System.out.println(student.getName() + "||" + student.getScore());
        
        
        
        Class clzStu = Student.class;
        Object objStu = clzStu.newInstance();
        Field name = clzStu.getDeclaredField("name");
        Field score = clzStu.getDeclaredField("score");
        name.setAccessible(true);
        score.setAccessible(true);
        name.set(objStu, "chenliu");
        score.set(objStu, 90);
        Student s1 = (Student) objStu;
        System.out.println(s1.getName() + s1.getScore());
        
        HelloSpeaker.helloTest("测试而已");
        
        //静态代理
        HelloSpeak proxy = new HelloProxy(new HelloSpeaker());
        proxy.hello("Tom");
        
        LoggingHandler loggingHandler = new LoggingHandler();
        HelloSpeak helloProxy = (HelloSpeak) loggingHandler.bind(new HelloSpeaker());
        helloProxy.hello("Jerry");
        

        
    }

    
    public static void view(String className) throws ClassNotFoundException{
    
        Class cl = Class.forName(className);
        showPackageInfo(cl);
        
        showClassInfo(cl);
        
        System.out.println("");
        
        showFiledsInfo(cl);
        showConstructorsInfo(cl);
        showMethodsInfo(cl);
        
    }
    
    private static void showPackageInfo(Class clz){
    
        Package p = clz.getPackage();//取得包代表对象
        System.out.println("package" + p.getName());
    }

    private static void showClassInfo(Class clz){
        int modifier = clz.getModifiers();//取得类型修饰常数
        System.out.println(Modifier.toString(modifier) //将常数转换为字符串表示
                + (Modifier.isInterface(modifier) ? "interface" : "class") 
                + clz.getName());//取得类名称
    }
    
    private static void showFiledsInfo(Class clz) throws SecurityException{
    
        //取得声明的数据成员代表对象
        Field[] fields = clz.getDeclaredFields();
        for (Field field : fields) {
            //显示权限修饰，
            System.out.println(Modifier.toString(field.getModifiers()) 
                    + field.getType().getName() //显示类型名称
                    + field.getName());//显示数据成员名称
        }
    }
    
    private static void showConstructorsInfo(Class clz) throws ClassNotFoundException{
        //取得声明的创建方法代表对象
        
        Constructor[] constructors = clz.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            //显示权限修饰
            System.out.println(Modifier.toString(constructor.getModifiers()) 
                    + constructor.getName());//显示构造函数名称
        }
    }
    
    private static void showMethodsInfo(Class clz) throws SecurityException {
        Method[] methods = clz.getDeclaredMethods();//取得声明的方法成员代表对象
        for (Method method : methods) {
            //显示权限修饰，
            System.out.println(Modifier.toString(method.getModifiers())
                    + method.getReturnType() //显示返回值类型名称
                    + method.getName()); //显示方法名称
        }
    }
    
    static {
        System.out.println("这里是Reflect的静态区块");
    }

  
}
